package com.angus.modules.content.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.angus.modules.content.domain.SysUnit;
import com.angus.modules.content.domain.SysOrder;
import com.angus.modules.content.dto.SetFeeDto;
import com.angus.modules.content.repository.SysOrderRepository;
import com.angus.modules.content.repository.SysUnitRepository;
import com.angus.modules.content.service.ISysUnitService;
import com.angus.modules.content.vo.SysUnitVo;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author liyanan
 */
@Service
public class SysUnitServiceImpl implements ISysUnitService {

    private static final Logger log = LoggerFactory.getLogger(SysUnitServiceImpl.class);

    @Resource
    private SysUnitRepository sysUnitRepository;

    @Resource
    private SysOrderRepository sysOrderRepository;

    private static final Integer GROUP_COUNT = 50;

    @Override
    public void addUnitToMax(Integer key, String operatorName, String courseCode) {
        Integer maxUnitNum = sysUnitRepository.selectMaxUnitNum(courseCode);
        if(Objects.isNull(maxUnitNum)){
            maxUnitNum = 1;
        }
        Long count = sysUnitRepository.selectGroupCountByUnitNum(maxUnitNum,courseCode);
        SysUnit unit = new SysUnit();
        if (count >= GROUP_COUNT) {
            maxUnitNum++;
        }
        long groupID = Long.parseLong(String.valueOf(key));
        List<SysUnit> groupList = sysUnitRepository.selectGroupID(courseCode,maxUnitNum,groupID);
        if (!CollUtil.isNotEmpty(groupList)){
            unit.setUnitNum(maxUnitNum);
            unit.setGroupId(Long.parseLong(String.valueOf(key)));
            unit.setIsPay(1);
            unit.setCreateTime(LocalDateTime.now());
            unit.setCreateBy(operatorName);
            unit.setCourseCode(courseCode);
            sysUnitRepository.save(unit);
        }
    }

    @Override
    public List<SysUnit> queryClusterByUnits(String courseCode, Integer unitNum) {
        return sysUnitRepository.selectUnits(courseCode,unitNum);
    }

    @Override
    public List<SysUnitVo> queryUnits(String courseCode, Long userID) {
        List<SysUnit> sysUnits = sysUnitRepository.selectAllUnits(courseCode);
        List<SysUnitVo>  voList = CollUtil.newArrayList();
        if(CollUtil.isNotEmpty(sysUnits)) {
            Map<Integer, List<SysUnit>> unitMap = sysUnits.stream().collect(Collectors.groupingBy(SysUnit::getUnitNum));
            for (Map.Entry<Integer, List<SysUnit>> entry : unitMap.entrySet()) {
                Integer unitNum = entry.getKey();
                List<SysUnit> unitList = entry.getValue();
                if (CollUtil.isNotEmpty(unitList)) {
                    SysUnitVo vo = new SysUnitVo();
                    vo.setUnitNum(unitNum);
                    SysUnit firstUnit = unitList.get(0);
                    vo.setCourseCode(firstUnit.getCourseCode());
                    vo.setIsPay(firstUnit.getIsPay());
                    voList.add(vo);
                }
            }
        }
        return voList;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeUnit(String courseCode, Integer unitNum) {
        sysUnitRepository.getBaseMapper().delete(Wrappers.lambdaQuery(SysUnit.class)
                .eq(SysUnit::getCourseCode, courseCode)
                .eq(SysUnit::getUnitNum, unitNum));
        // 更新后续单元的编号
        List<SysUnit> unitsToUpdate = sysUnitRepository.list(Wrappers
                .lambdaQuery(SysUnit.class)
                .gt(SysUnit::getUnitNum, unitNum));
        for (SysUnit unit : unitsToUpdate) {
            unit.setUnitNum(unit.getUnitNum() - 1);
            sysUnitRepository.updateById(unit);
        }
    }

    @Override
    public boolean setContentFee(SetFeeDto dto) {
     return sysUnitRepository.setContentFee(dto.getUnitNums(),
             dto.getCourseCode(),dto.getIsPay());

    }
}
